/**
 * 
 */
package com.goktech.commons.excel.utils.abs;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.Workbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.goktech.commons.excel.Excel;
import com.goktech.commons.excel.utils.ValueSelector;
import com.goktech.commons.utils.PropertyUtils;

/**
 * @author 24252
 * 
 *         读抽象
 * 
 *         都需要输入流 结果集list
 */
public abstract class AbstractReader<T> extends AbstractExcel<T> {

	protected final Logger logger = LoggerFactory.getLogger(clazz);

	protected Map<Integer, Field> fieldMap;

	protected Map<String, Field> temp;

	protected boolean isEnd = false;
	
	protected boolean isSync = false;
	
	protected InputStream is;
	
	public  Workbook workbook = null;
	
	protected List<Object> resultList = new ArrayList<>();

	public AbstractReader(Class<?> clazz,InputStream is) {
		super(clazz);
		this.is = is;
		initContainer();
	}

	/**
	 * 初始化内部容器的方法，一般用户二次解析excel
	 * 
	 * @return
	 */
	public T initContainer() {
		temp = new HashMap<>();
		fieldMap = new HashMap<>();
		propertyUtils = new PropertyUtils(this.clazz);
		Field[] fields = clazz.getDeclaredFields();
		while (fields != null && fields.length > 0) {
			for (Field field : fields) {
				Excel excel = field.getAnnotation(Excel.class);
				if (excel != null) {
					temp.put(excel.name(), field);
				}
			}
			fields = clazz.getSuperclass().getDeclaredFields();
		}
		if (logger.isDebugEnabled())
			logger.debug("init container success temp size {}", temp.size());
		return this.getSelf();
	}

	/**
	 * 初始化表头使之与字段对其
	 * @param rowList
	 * @return
	 */
	public T initTitle(List<String> rowList) {
		for (int i = 0; i < rowList.size(); i++) {
			if (temp.get(rowList.get(i)) != null) {
				if (logger.isDebugEnabled())
					logger.debug("{} : {}", rowList.get(i), temp.get(rowList.get(i)));
				fieldMap.put(i, temp.get(rowList.get(i)));
			}
		}
		resultList = new ArrayList<>();
		return this.getSelf();
	}

	public T putData(List<String> rowList) {
		Object obj = null;
		try {
			obj = clazz.newInstance();
		} catch (InstantiationException e) {
			logger.error("{}对象创建失败", clazz.getName());
			return this.getSelf();
		} catch (IllegalAccessException e) {
			logger.error("{}对象创建失败", clazz.getName());
			return this.getSelf();
		}
		for (int i = 0; i < rowList.size(); i++) {
			Object value = ValueSelector.getValue(rowList.get(i), fieldMap.get(i));
			if (logger.isDebugEnabled()) {
				int size = resultList.size();
				logger.debug("行：{} 列：{} field:{} value:{}", size, i, fieldMap.get(i).getName(), value);
			}
			propertyUtils.setCacheProperty(obj, fieldMap.get(i).getName(), value);
		}
		this.resultList.add(obj);
		return this.getSelf();
	}
	
	public abstract T run();
	/**
	 * 返回获取的结果
	 * @return
	 */
	public List<?> getList() {
		List<Object> result = new ArrayList<>(this.resultList);
		return result;
	}
}
